package com.jinmdz.fmis.api.api.service;

import com.jinmdz.fmis.api.api.model.funeral.BusinessCodeData;
import com.jinmdz.fmis.api.api.model.funeral.agreement.ServiceAgreementChargeItem;
import com.jinmdz.fmis.api.api.model.funeral.agreement.ServiceAgreementItem;
import com.jinmdz.fmis.api.api.model.funeral.negotiation.*;
import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.api.constant.MessageConst;
import com.jinmdz.fmis.api.wrapper.DictionaryWrapper;
import com.jinmdz.fmis.common.util.BeanUtil;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.common.util.RenminbiUtil;
import com.jinmdz.fmis.core.base.BaseResult;
import com.jinmdz.fmis.core.constant.Constants;
import com.jinmdz.fmis.core.constant.EBusinessType;
import com.jinmdz.fmis.dao.dao.*;
import com.jinmdz.fmis.dao.model.charge.ChargeItem;
import com.jinmdz.fmis.dao.model.coldstorage.ColdStorageViewItem;
import com.jinmdz.fmis.dao.model.cremation.CremationViewItem;
import com.jinmdz.fmis.dao.model.facelift.FaceLiftChargeItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyAgentItem;
import com.jinmdz.fmis.dao.model.funeral.FamilyMemberItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralBusinessViewItem;
import com.jinmdz.fmis.dao.model.funeral.FuneralDeadItem;
import com.jinmdz.fmis.dao.model.mourn.MournCeremonyViewItem;
import com.jinmdz.fmis.dao.model.transport.TransportTaskItem;
import com.jinmdz.fmis.dao.model.transport.TransportTaskViewItem;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * ServiceNegotiationService类
 *
 * @author LiCongLu
 * @date 2020-01-13 11:38
 */
@Service("serviceNegotiationService")
public class ServiceNegotiationService extends BaseService {

    @Resource
    private FuneralBusinessDao funeralBusinessDao;

    @Resource
    private FuneralDeadDao funeralDeadDao;

    @Resource
    private FamilyMemberDao familyMemberDao;

    @Resource
    private FamilyAgentDao familyAgentDao;

    @Resource
    private DictionaryWrapper dictionaryWrapper;

    @Resource
    private TransportTaskDao transportTaskDao;

    @Resource
    private ColdStorageDao coldStorageDao;

    @Resource
    private MournCeremonyDao mournCeremonyDao;

    @Resource
    private CremationDao cremationDao;

    @Resource
    private ChargeItemDao chargeItemDao;

    @Resource
    private FaceLiftItemDao faceLiftItemDao;

    /**
     * 根据funeral_dead表中businessCode加载服务洽谈登记信息
     *
     * @param data 业务编码数据
     * @return
     * @author LiCongLu
     * @date 2020-02-11 11:31
     */
    public BaseResult<ServiceNegotiationItem> loadServiceNegotiationWithBusinessCode(BusinessCodeData data) {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            return failure(MessageConst.NO_FUNERAL_CODE);
        }

        // 创建响应实体
        ServiceNegotiationItem loadItem = new ServiceNegotiationItem();

        // 获取逝者信息
        FuneralDeadItem funeralDeadItem = funeralDeadDao.getFuneralDeadByBusinessCode(businessCode);
        NegotiationDeadItem deadItem = BeanUtil.copy2Bean(funeralDeadItem, new NegotiationDeadItem());
        // 设置字典文本
        dictionaryWrapper.resetDataText(deadItem);
        loadItem.setFuneralDead(deadItem);

        // 获取家属信息
        FamilyMemberItem familyMemberItem = familyMemberDao.getFamilyMemberByBusinessCode(businessCode);
        NegotiationMemberItem memberItem = BeanUtil.copy2Bean(familyMemberItem, new NegotiationMemberItem());
        loadItem.setFamilyMember(memberItem);

        // 获取承办人信息
        FamilyAgentItem familyAgentItem = familyAgentDao.getFamilyAgentByBusinessCode(businessCode);
        NegotiationAgentItem agentItem = BeanUtil.copy2Bean(familyAgentItem, new NegotiationAgentItem());
        loadItem.setFamilyAgent(agentItem);

        // 获取业务费用及物品服务
        ArrayList<ChargeItem> chargeItems = chargeItemDao.listChargeItemByBusinessCode(businessCode);
        // 加载各个业务及费用信息
        loadServiceNegotiationWithBusinessCode(businessCode, loadItem, chargeItems);

        // 获取丧葬用品
        String businessType = EBusinessType.TYPE_OF_FUNERAL_SUPPLIES.getType();
        NegotiationBusinessCharges businessCharges = getBusinessCharges(chargeItems, businessType, 0);
        loadItem.setFuneralSuppliesTasks(businessCharges.getGoodsServices());

        // 返回响应结果
        return successData(loadItem);
    }

    /**
     * 加载各个业务及费用信息
     *
     * @param businessCode 业务编码
     * @param loadItem     加载数据
     * @param chargeItems  费用集合
     * @return
     * @author LiCongLu
     * @date 2020-05-13 13:31
     */
    private void loadServiceNegotiationWithBusinessCode(String businessCode, ServiceNegotiationItem loadItem, ArrayList<ChargeItem> chargeItems) {
        // 获取接运任务信息
        ArrayList<TransportTaskViewItem> transportTaskItems = transportTaskDao.listTransportTaskViewByBusinessCode(businessCode);
        if (transportTaskItems != null && transportTaskItems.size() > 0) {
            ArrayList<NegotiationTransportItem> negotiationItems = new ArrayList<>();
            for (TransportTaskItem transportTaskItem : transportTaskItems) {
                NegotiationTransportItem negotiationItem = BeanUtil.copy2Bean(transportTaskItem, new NegotiationTransportItem());
                negotiationItem.setCharges(getBusinessCharges(chargeItems, transportTaskItem.getRandomCode(), transportTaskItem.getChargeId()));
                negotiationItems.add(negotiationItem);
            }
            // 初始化字典文本
            dictionaryWrapper.resetDataText(negotiationItems);
            loadItem.setTransportTasks(negotiationItems);
        }

        // 获取冷藏信息
        ArrayList<ColdStorageViewItem> coldStorageViewItems = coldStorageDao.listColdStorageViewByBusinessCode(businessCode);
        if (coldStorageViewItems != null && coldStorageViewItems.size() > 0) {
            ArrayList<NegotiationColdStorageItem> negotiationItems = new ArrayList<>();
            for (ColdStorageViewItem coldStorageViewItem : coldStorageViewItems) {
                NegotiationColdStorageItem negotiationItem = BeanUtil.copy2Bean(coldStorageViewItem, new NegotiationColdStorageItem());
                negotiationItem.setCharges(getBusinessCharges(chargeItems, coldStorageViewItem.getRandomCode(), coldStorageViewItem.getChargeId()));
                negotiationItems.add(negotiationItem);
            }
            // 初始化字典文本
            dictionaryWrapper.resetDataText(negotiationItems);
            loadItem.setColdStorageTasks(negotiationItems);
        }

        // 查询所有整容费用
        ArrayList<FaceLiftChargeItem> faceLiftChargeItems = faceLiftItemDao.listFaceLiftChargeByBusinessCode(businessCode);
        if (faceLiftChargeItems != null && faceLiftChargeItems.size() > 0) {
            ArrayList<NegotiationFaceLiftItem> negotiationItems = new ArrayList<>();
            ArrayList<Integer> chargeIds = new ArrayList<>();
            for (FaceLiftChargeItem faceLiftChargeItem : faceLiftChargeItems) {
                NegotiationFaceLiftItem negotiationItem = BeanUtil.copy2Bean(faceLiftChargeItem, new NegotiationFaceLiftItem());
                negotiationItems.add(negotiationItem);
                chargeIds.add(faceLiftChargeItem.getChargeId());
            }
            //随机码
            String randomCode = EBusinessType.TYPE_OF_FACE_LIFT.getType();
            // 加载整容退费的费用
            for (ChargeItem chargeItem : chargeItems) {
                // 判断整容相关费用里，非整容费用即整容退费信息
                if (DataUtil.equals(randomCode, chargeItem.getRandomCode())
                        && !chargeIds.contains(chargeItem.getId())) {
                    // 覆盖数据
                    NegotiationFaceLiftItem negotiationItem = BeanUtil.copy2Bean(chargeItem, new NegotiationFaceLiftItem());
                    // 重置整容主键，设置费用主键信息
                    negotiationItem.setId(0).setChargeId(chargeItem.getId())
                            .setVersion(0L).setChargeVersion(chargeItem.getVersion());
                    negotiationItems.add(negotiationItem);
                }
            }
            loadItem.setFaceLiftTasks(negotiationItems);
        }

        // 获取礼厅信息
        ArrayList<MournCeremonyViewItem> mournCeremonyViewItems = mournCeremonyDao.listMournCeremonyViewByBusinessCode(businessCode);
        if (mournCeremonyViewItems != null && mournCeremonyViewItems.size() > 0) {
            ArrayList<NegotiationWakeMournItem> wakeMournItems = new ArrayList<>();
            ArrayList<NegotiationFarewellMournItem> farewellMournItems = new ArrayList<>();
            // 遍历并区分守灵与告别
            for (MournCeremonyViewItem mournCeremonyViewItem : mournCeremonyViewItems) {
                if (Constants.WAKE_MOURN_TYPE.equals(mournCeremonyViewItem.getBusinessType())) {
                    NegotiationWakeMournItem negotiationItem = BeanUtil.copy2Bean(mournCeremonyViewItem, new NegotiationWakeMournItem());
                    negotiationItem.setCharges(getBusinessCharges(chargeItems, mournCeremonyViewItem.getRandomCode(), mournCeremonyViewItem.getChargeId()));
                    wakeMournItems.add(negotiationItem);
                } else if (Constants.FAREWELL_MOURN_TYPE.equals(mournCeremonyViewItem.getBusinessType())) {
                    NegotiationFarewellMournItem negotiationItem = BeanUtil.copy2Bean(mournCeremonyViewItem, new NegotiationFarewellMournItem());
                    negotiationItem.setCharges(getBusinessCharges(chargeItems, mournCeremonyViewItem.getRandomCode(), mournCeremonyViewItem.getChargeId()));
                    farewellMournItems.add(negotiationItem);
                }
            }

            // 初始化字典文本
            dictionaryWrapper.resetDataText(wakeMournItems);
            dictionaryWrapper.resetDataText(farewellMournItems);
            loadItem.setWakeMournTasks(wakeMournItems);
            loadItem.setFarewellMournTasks(farewellMournItems);
        }

        // 获取火化信息
        ArrayList<CremationViewItem> cremationViewItems = cremationDao.listCremationViewByBusinessCode(businessCode);
        if (cremationViewItems != null && cremationViewItems.size() > 0) {
            ArrayList<NegotiationCremationItem> negotiationItems = new ArrayList<>();
            for (CremationViewItem cremationViewItem : cremationViewItems) {
                NegotiationCremationItem negotiationItem = BeanUtil.copy2Bean(cremationViewItem, new NegotiationCremationItem());
                negotiationItem.setCharges(getBusinessCharges(chargeItems, cremationViewItem.getRandomCode(), cremationViewItem.getChargeId()));
                negotiationItems.add(negotiationItem);
            }
            // 初始化字典文本
            dictionaryWrapper.resetDataText(negotiationItems);
            loadItem.setCremationTasks(negotiationItems);
        }
    }

    /**
     * 获取业务费用及物品服务
     *
     * @param chargeItems 所有费用集合
     * @param randomCode  业务随机码
     * @param chargeId    业务费用主键
     * @return
     * @author LiCongLu
     * @date 2020-02-16 17:19
     */
    private NegotiationBusinessCharges getBusinessCharges(ArrayList<ChargeItem> chargeItems, String randomCode, Integer chargeId) {
        // 防止对比错误
        if (chargeId == null) {
            chargeId = 0;
        }
        // 业务费用
        ChargeItem businessCharge = null;
        // 物品服务
        ArrayList<ChargeItem> goodsServices = new ArrayList<>();
        Iterator<ChargeItem> iterator = chargeItems.iterator();
        while (iterator.hasNext()) {
            ChargeItem chargeItem = iterator.next();
            // 统一业务随机码内，除了业务费用就是物品服务
            if (randomCode.equals(chargeItem.getRandomCode())) {
                if (chargeItem.getId().intValue() == chargeId.intValue()) {
                    businessCharge = chargeItem;
                } else {
                    goodsServices.add(chargeItem);
                }
                iterator.remove();
            }
        }
        NegotiationBusinessCharges businessCharges = new NegotiationBusinessCharges();
        businessCharges.setBusinessCharge(businessCharge).setGoodsServices(goodsServices);
        return businessCharges;
    }

    /**
     * 根据funeral_dead表中businessCode加载打印服务协议单
     *
     * @param data 业务编码数据
     * @return
     * @author LiCongLu
     * @date 2020-04-10 09:41
     */
    public BaseResult<ServiceAgreementItem> loadPrintServiceAgreementWithBusinessCode(BusinessCodeData data) {
        String businessCode = data.getBusinessCode();
        // 通过业务编码获取殡葬信息
        FuneralBusinessViewItem funeralItem = funeralBusinessDao.getFuneralBusinessViewByBusinessCode(businessCode);
        if (DataUtil.isNull(funeralItem) || DataUtil.isNull(funeralItem.getId(), funeralItem.getVersion())) {
            return failure(MessageConst.NO_FUNERAL_CODE);
        }

        // 创建响应实体
        ServiceAgreementItem loadItem = new ServiceAgreementItem();
        // 殡葬信息
        loadItem.setBusinessCode(businessCode)
                .setBusinessTime(funeralItem.getBusinessTime());

        // 获取逝者信息
        FuneralDeadItem funeralDeadItem = funeralDeadDao.getFuneralDeadByBusinessCode(businessCode);
        BeanUtil.copy2Bean(funeralDeadItem, loadItem);

        // 获取家属信息
        FamilyMemberItem familyMemberItem = familyMemberDao.getFamilyMemberByBusinessCode(businessCode);
        BeanUtil.copy2Bean(familyMemberItem, loadItem);

        // 初始化字典文本
        dictionaryWrapper.resetDataText(loadItem);

        // 获取业务费用及物品服务
        ArrayList<ChargeItem> chargeAllItems = chargeItemDao.listChargeItemByBusinessCode(businessCode);

        // 服务费用列表
        ArrayList<ServiceAgreementChargeItem> chargeItems = new ArrayList<>();

        // 优惠费用信息
        ArrayList<ServiceAgreementChargeItem> discountChargeItems = new ArrayList<>();
        // 惠民费用信息
        ArrayList<ServiceAgreementChargeItem> benefitChargeItems = new ArrayList<>();

        // 遍历费用，进行解析
        for (ChargeItem chargeItem : chargeAllItems) {

            // 优惠金额
            if (DataUtil.greaterAllZero(chargeItem.getDiscountCharge())) {
                discountChargeItems.add(new ServiceAgreementChargeItem()
                        .setServiceItemId(chargeItem.getServiceItemId())
                        .setItemName(chargeItem.getItemName())
                        .setItemCharge(chargeItem.getDiscountCharge()));
                loadItem.setDiscountTotalCharge(DataUtil.add(loadItem.getDiscountTotalCharge(), chargeItem.getDiscountCharge()));
            }

            // 惠民金额
            if (DataUtil.greaterAllZero(chargeItem.getBenefitCharge())) {
                benefitChargeItems.add(new ServiceAgreementChargeItem()
                        .setServiceItemId(chargeItem.getServiceItemId())
                        .setItemName(chargeItem.getItemName())
                        .setItemCharge(chargeItem.getBenefitCharge()));
                loadItem.setBenefitTotalCharge(DataUtil.add(loadItem.getBenefitTotalCharge(), chargeItem.getBenefitCharge()));
            }

            // 服务费用列表
            chargeItems.add(new ServiceAgreementChargeItem()
                    .setServiceItemId(chargeItem.getServiceItemId())
                    .setItemName(chargeItem.getItemName())
                    .setItemCharge(chargeItem.getItemCharge()));
            // 费用金额
            loadItem.setItemTotalCharge(DataUtil.add(loadItem.getItemTotalCharge(), chargeItem.getItemCharge()));
            // 实收金额
            loadItem.setRealityTotalCharge(DataUtil.add(loadItem.getRealityTotalCharge(), chargeItem.getRealityCharge()));
        }

        // 显示大写
        loadItem.setRealityTotalChargeText(RenminbiUtil.toRmb(loadItem.getRealityTotalCharge()));

        // 设置合并项目后的集合
        loadItem.setChargeItems(repeatSumChargeItems(chargeItems));
        loadItem.setDiscountChargeItems(repeatSumChargeItems(discountChargeItems));
        loadItem.setBenefitChargeItems(repeatSumChargeItems(benefitChargeItems));
        return successData(loadItem);
    }

    /**
     * 去重整合金额
     *
     * @param chargeItems 费用集合
     * @return
     * @author LiCongLu
     * @date 2020-04-10 13:12
     */
    public ArrayList<ServiceAgreementChargeItem> repeatSumChargeItems(ArrayList<ServiceAgreementChargeItem> chargeItems) {
        ArrayList<ServiceAgreementChargeItem> agreementChargeItems = new ArrayList<>();
        HashMap<Integer, ServiceAgreementChargeItem> chargeMap = new HashMap<>(16);
        // 遍历合并
        for (ServiceAgreementChargeItem chargeItem : chargeItems) {
            Integer key = chargeItem.getServiceItemId();
            if (chargeMap.containsKey(key)) {
                ServiceAgreementChargeItem value = chargeMap.get(key);
                value.setItemCharge(DataUtil.add(value.getItemCharge(), chargeItem.getItemCharge()));
                continue;
            }
            chargeMap.put(key, BeanUtil.copy2Bean(chargeItem, new ServiceAgreementChargeItem()));
        }
        // 遍历返回结果集
        for (Map.Entry<Integer, ServiceAgreementChargeItem> entry : chargeMap.entrySet()) {
            agreementChargeItems.add(entry.getValue());
        }
        return agreementChargeItems;
    }
}
